import os
import time
import tkinter as tk
from tkinter import ttk, messagebox, simpledialog
from typing import List

from langchain.tools import tool

from Impl.user_title_impl import UserTitleImpl
from Impl.wav_impl import WavImpl
from Mapper.wav_mapper import WavFile
from config import DB_CONFIG, ADMIN_PASSWORD
from utils.audio_recorder import record_and_convert

# 全局实例
_websocket_server = None
_voice_worker = None
_is_shutting_down = False


def set_global_instances(websocket_server=None, voice_worker=None):
    """设置全局实例"""
    global _websocket_server, _voice_worker
    _websocket_server = websocket_server
    _voice_worker = voice_worker


def set_shutdown_flag():
    """设置关闭标志"""
    global _is_shutting_down
    _is_shutting_down = True


def _select_titles() -> List[str]:
    """职称多选对话框"""
    selected_titles = []

    # 创建选择窗口
    root = tk.Tk()
    root.title("选择职称")
    root.geometry("400x400")
    root.attributes('-topmost', True)

    # 职称选项
    titles = [
        "数据录入员(L1)",
        "数据分析师(L2)",
        "系统工程师(L3)",
        "技术专家(L4)",
        "智能制造总监(L5)",
        "数据采集员(L1)",
        "栽培专家(L3)",
        "系统工程师(L4)",
        "智慧农业总监(L5)"
    ]

    # 变量存储选择状态
    var_list = []
    for title in titles:
        var = tk.BooleanVar()
        var_list.append((title, var))
        cb = ttk.Checkbutton(root, text=title, variable=var)
        cb.pack(anchor="w", padx=20, pady=5)

    # 确认按钮
    def on_ok():
        nonlocal selected_titles
        selected_titles = [title for title, var in var_list if var.get()]
        root.destroy()

    # 取消按钮
    def on_cancel():
        root.destroy()

    # 按钮框架
    btn_frame = ttk.Frame(root)
    btn_frame.pack(side="bottom", pady=20)

    ok_btn = ttk.Button(btn_frame, text="确定", command=on_ok)
    ok_btn.pack(side="left", padx=20)

    cancel_btn = ttk.Button(btn_frame, text="取消", command=on_cancel)
    cancel_btn.pack(side="right", padx=20)

    # 等待窗口关闭
    root.mainloop()

    return selected_titles


@tool("add_voiceprint", description="注册声纹特征")
def add_voiceprint() -> str:
    """极简版声纹注册 - 职称多选"""
    if _is_shutting_down:
        return "❌ 程序正在关闭"

    try:
        # 1. 密码验证
        password = simpledialog.askstring("权限验证", "管理员密码:", show='*')
        if not password or password != ADMIN_PASSWORD:
            return "❌ 密码验证失败"

        # 2. 英文名
        english_name = simpledialog.askstring("声纹注册", "英文名:")
        if not english_name:
            return "❌ 未输入英文名"
        english_name = english_name.strip()

        # 检查重复
        with WavImpl(DB_CONFIG) as wav_impl:
            if wav_impl.check_user_english_name_exists(english_name):
                return f"❌ 英文名 '{english_name}' 已存在"

        # 3. 中文名（可选）
        chinese_name = simpledialog.askstring("声纹注册", "中文名（可选）:") or ""

        # 4. 职称选择（多选）
        selected_titles = _select_titles()
        if not selected_titles:
            return "❌ 未选择任何职称"

        # 显示选择结果确认
        titles_text = "\n- " + "\n- ".join(selected_titles)
        if not messagebox.askyesno("确认职称选择", f"您选择了以下职称：{titles_text}\n\n确认选择？"):
            return "❌ 用户取消操作"

        # 5. 录制确认
        if not messagebox.askyesno("录制确认", "开始录制音频？"):
            return "❌ 用户取消录制"

        # 6. 录制音频
        try:
            wav_path, mp3_path = record_and_convert(f"voiceDB_{english_name}", duration=4)
        except Exception as e:
            return f"❌ 录制失败: {str(e)}"

        # 7. 保存数据（使用第一个职称为主职称）
        main_title = selected_titles[0] if selected_titles else "数据录入员(L1)"

        with open(mp3_path, 'rb') as f:
            wav_file = WavFile(
                user_english_name=english_name,
                user_chinese_name=chinese_name.strip(),
                user_identity="|".join(selected_titles),  # 存储所有选择的职称
                audio_type='1',
                file_data=f.read(),
                upload_time=time.strftime('%Y-%m-%d %H:%M:%S')
            )

        with WavImpl(DB_CONFIG) as wav_impl:
            inserted_id = wav_impl.insert_wav(wav_file)

        # 保存所有职称信息
        if inserted_id:
            for title in selected_titles:
                title_parts = title.split("(")
                # 根据职称名称确定业务类型
                if "数据录入员" in title or "数据分析师" in title or "系统工程师" in title or "技术专家" in title or "智能制造总监" in title:
                    business_type = "mechanical_arm"
                else:
                    business_type = "flower"
                    
                # 修复UserTitleMapping初始化参数问题
                from Mapper.user_title_mapper import UserTitleMapping
                user_title = UserTitleMapping(
                    user_id=inserted_id,
                    business_type=business_type,  # 使用正确的业务类型
                    title_name=title_parts[0],
                    level=title_parts[1].rstrip(")") if len(title_parts) > 1 else "L1",
                    grant_date=time.strftime('%Y-%m-%d')
                )
                
                with UserTitleImpl(DB_CONFIG) as title_impl:
                    title_impl.insert_user_title(user_title)
                
                # 同步到云端数据库
                try:
                    from Mapper.voiceDB_mapper import req_url
                    from config import VOICE_APP_ID, VOICE_API_KEY, VOICE_API_SECRET, VOICE_DB_GROUP_NAME, VOICE_DB_GROUP_ID
                    
                    response = req_url(
                        api_name='createFeature',
                        APPId=VOICE_APP_ID,
                        APIKey=VOICE_API_KEY,
                        APISecret=VOICE_API_SECRET,
                        file_path=mp3_path,
                        group_name=VOICE_DB_GROUP_NAME,
                        group_id=VOICE_DB_GROUP_ID,
                        user_id=str(inserted_id),
                        user=english_name
                    )
                    print(f"🔊 云端声纹库上传结果: {response}")
                except Exception as e:
                    print(f"⚠️ 上传声纹到云端失败: {str(e)}")

        # 清理文件
        for path in [wav_path, mp3_path]:
            os.remove(path) if os.path.exists(path) else None

        # 格式化返回结果
        titles_display = ", ".join(selected_titles)
        return f"✅ 注册成功！用户: {english_name} ({titles_display})"

    except Exception as e:
        return f"❌ 注册失败: {str(e)}"


@tool("delete_voiceprint", description="删除声纹特征")
def delete_voiceprint() -> str:
    """删除声纹"""
    try:
        # 密码验证
        password = simpledialog.askstring("权限验证", "管理员密码:", show='*')
        if not password or password != ADMIN_PASSWORD:
            return "❌ 密码验证失败"

        english_name = simpledialog.askstring("删除声纹", "要删除的用户名:")
        if not english_name:
            return "❌ 未输入用户名"

        # 执行删除逻辑
        with WavImpl(DB_CONFIG) as wav_impl:
            wav_files = wav_impl.get_wav_by_user_english_name(english_name)
            if not wav_files:
                return f"❌ 用户 '{english_name}' 不存在"

            user_id = wav_files[0].id
            wav_impl.delete_wav_by_user_english_name(english_name)

        # 删除所有相关业务类型的职称记录
        with UserTitleImpl(DB_CONFIG) as title_impl:
            title_impl.delete_user_title_by_user_id_and_business_type(user_id, "mechanical_arm")
            title_impl.delete_user_title_by_user_id_and_business_type(user_id, "flower")

        # 同步删除云端声纹数据
        try:
            from Mapper.voiceDB_mapper import req_url
            from config import VOICE_APP_ID, VOICE_API_KEY, VOICE_API_SECRET, VOICE_DB_GROUP_NAME, VOICE_DB_GROUP_ID
            
            response = req_url(
                api_name='deleteFeature',
                APPId=VOICE_APP_ID,
                APIKey=VOICE_API_KEY,
                APISecret=VOICE_API_SECRET,
                group_name=VOICE_DB_GROUP_NAME,
                group_id=VOICE_DB_GROUP_ID,
                user_id=str(user_id),
                user=english_name
            )
            print(f"🔊 云端声纹库删除结果: {response}")
        except Exception as e:
            print(f"⚠️ 删除云端声纹数据失败: {str(e)}")

        return f"✅ 删除成功: {english_name}"

    except Exception as e:
        return f"❌ 删除失败: {str(e)}"